# -*- coding: utf-8 -*-
import os
import re
import time
import sys
import docxtpl
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt, QDate
from pandas import DataFrame
from docxtpl import DocxTemplate
from SLP_UI import SLP_Ui_MainWindow
import pandas  as pd

tpl = DocxTemplate('./标签样式/标签模板.docx')


class SLP(QtWidgets.QMainWindow, SLP_Ui_MainWindow):

    def __init__(self):
        super(SLP, self).__init__()
        self.setupUi(self)
        self.sitesRoot = None
        self.itemsRoot = None
        self.curItemsList = []
        self.curSitesList = []
        self.intiui()

    def intiui(self):
        # 初始化tablewidget模块
        self.taskList_Table = TableWidgetClass(self.taskList)

        # 设置列数
        self.siteChoice.setColumnCount(1)
        # 设置树形控件头部的标题
        # self.siteChoice.setHeaderLabels(['全部点位'])
        self.siteChoice.setColumnWidth(0, 200)
        # 当Text太长显示不全时候，允许适应
        self.siteChoice.header().setSectionResizeMode(QHeaderView.ResizeToContents)
        self.siteChoice.header().setStretchLastSection(False)
        self.siteChoice.setAutoScroll(False)

        self.itemChoice.setColumnCount(1)
        # 设置树形控件头部的标题
        # self.siteChoice.setHeaderLabels(['全部点位'])
        self.itemChoice.setColumnWidth(0, 200)
        # 当Text太长显示不全时候，允许适应
        self.itemChoice.header().setSectionResizeMode(QHeaderView.ResizeToContents)
        self.itemChoice.header().setStretchLastSection(False)
        self.itemChoice.setAutoScroll(False)

        # 设置根节点
        self.sitesRoot = QTreeWidgetItem(self.siteChoice)
        self.sitesRoot.setText(0, '全部点位')
        self.sitesRoot.setCheckState(0, Qt.Unchecked)
        self.sitesRoot.setExpanded(True)
        self.itemsRoot = QTreeWidgetItem(self.itemChoice)
        self.itemsRoot.setText(0, '全部项目')
        self.itemsRoot.setCheckState(0, Qt.Unchecked)
        self.itemsRoot.setExpanded(True)

        self.sampleDate.setDate(QDate.currentDate())

        files = os.listdir(os.path.join(os.path.curdir, '基础信息', '点位信息'))
        files = [f for f in files if not (f.startswith('~') or f.startswith('.'))]
        fileNames = [i.split(".")[0] for i in files][::-1]
        for file in fileNames:
            self.siteTypeChoice.addItem(file)
        self.siteTypeChoice.currentIndexChanged.connect(self.siteTypeSelectionChange)
        self.siteTypeSelectionChange(0)
        self.itemsSelection()
        # 节点全部展开
        # self.siteChoice.expandAll()

        self.siteChoice.itemChanged.connect(self.site_handlechanged)
        self.itemChoice.itemChanged.connect(self.item_handlechanged)
        self.tableAppend.clicked.connect(self.table_append)
        self.tableDel.clicked.connect(self.table_remove)
        self.labelMaker.clicked.connect(self.table_read)

    def site_handlechanged(self, item, column):
        # self.curSitesList.clear()
        count = item.childCount()
        # print('count:', count)
        # print('item.text(0):', item.text(0))
        # print('column:', column)
        if item.checkState(column) == Qt.Checked:
            if count == 0:  # 叶子节点
                # self.taskList_Table.table_append(item.text(0))
                if item.text(0) not in self.curSitesList:
                    self.curSitesList.append(item.text(0))
            for f in range(count):
                if item.child(f).checkState(0) != Qt.Checked:
                    item.child(f).setCheckState(0, Qt.Checked)
                    # self.taskList_Table.table_append(item.child(f).text(0))
                    if item.child(f).text(0) not in self.curSitesList:
                        if item.child(f).childCount() == 0:  # 叶子节点
                            self.curSitesList.append(item.child(f).text(0))

        if item.checkState(column) == Qt.Unchecked:
            if count == 0:
                # self.taskList_Table.table_remove(item.text(0))
                if item.text(0) in self.curSitesList:
                    self.curSitesList.remove(item.text(0))
            for f in range(count):
                if item.child(f).checkState != Qt.Unchecked:
                    item.child(f).setCheckState(0, Qt.Unchecked)
                    # self.taskList_Table.table_remove(item.text(0))
                    if item.text(0) in self.curSitesList:
                        self.curSitesList.remove(item.text(0))

        # print('curSitesList:', self.curSitesList)
        # self.taskList_Table.table_append(",".join(self.curSitesList))

    def item_handlechanged(self, item, column):
        count = item.childCount()
        if item.checkState(column) == Qt.Checked:
            if count == 0:
                if item.text(0) not in self.curItemsList:
                    self.curItemsList.append(item.text(0))
            for f in range(count):
                if item.child(f).checkState(0) != Qt.Checked:
                    item.child(f).setCheckState(0, Qt.Checked)
                    if item.child(f).text(0) not in self.curItemsList:
                        if item.child(f).childCount() == 0:
                            self.curItemsList.append(item.child(f).text(0))

        if item.checkState(column) == Qt.Unchecked:
            if count == 0:
                if item.text(0) in self.curItemsList:
                    self.curItemsList.remove(item.text(0))
            for f in range(count):
                if item.child(f).checkState != Qt.Unchecked:
                    item.child(f).setCheckState(0, Qt.Unchecked)
                    if item.text(0) in self.curItemsList:
                        self.curItemsList.remove(item.text(0))

        # print('curItemsList:', self.curItemsList)

    def siteTypeSelectionChange(self, index):
        self.sitesRoot.takeChildren()
        # print("combox select index", index)
        # print("combox select Text", self.siteTypeChoice.currentText())
        path = os.path.join(os.path.curdir, '基础信息', '点位信息', self.siteTypeChoice.currentText() + '.xlsx')
        # print("combox select path", path)
        df = pd.read_excel(path, keep_default_na=False, header=0, sheet_name=None)
        maxID = self.getMaxSampleID()
        maxPlusOne = self.sampleIDPlus1(maxID)
        # print('maxID,maxPlusOne: ',maxID,maxPlusOne)
        self.initsampleID.setText(maxPlusOne)

        for i in df.keys():
            # print(i)
            self.sitesType = QTreeWidgetItem(self.sitesRoot)
            self.sitesType.setText(0, i)
            self.sitesType.setCheckState(0, Qt.Unchecked)
            self.sitesType.setExpanded(False)
            sites_df = df[i]
            for index, row in sites_df.iterrows():
                # curNode = self.sitesType
                site = sites_df.loc[index].tolist()
                # items = self.siteChoice.findItems(site[0], Qt.MatchRecursive | Qt.MatchExactly, 0)  # Qt.MatchRecursive | Qt.MatchContains|Qt.MatchExactly
                listSubItem = []
                for index in range(0, self.sitesType.childCount()):
                    listSubItem.append(self.sitesType.child(index).text(0))
                # print('listSubItem:',listSubItem)
                if site[0] not in listSubItem:
                    self.sites1h = QTreeWidgetItem(self.sitesType)
                    self.sites1h.setText(0, site[0])
                    self.sites1h.setCheckState(0, Qt.Unchecked)
                else:
                    self.sites1h = self.sitesType.child(listSubItem.index(site[0]))

                # items2h = self.sites1h.findItems(site[1], Qt.MatchExactly, 0)
                self.sites2h = QTreeWidgetItem(self.sites1h)
                self.sites2h.setText(0, site[1])
                self.sites2h.setCheckState(0, Qt.Unchecked)

    def itemsSelection(self):
        self.itemsRoot.takeChildren()
        path = os.path.join(os.path.curdir, '基础信息', '监测项目信息.xlsx')
        df = pd.read_excel(path, keep_default_na=False, header=0, sheet_name=None)
        # print('items df' , df)
        for i in df.keys():
            self.itemTpye = QTreeWidgetItem(self.itemsRoot)
            self.itemTpye.setText(0, i)
            self.itemTpye.setCheckState(0, Qt.Unchecked)
            self.itemTpye.setExpanded(False)
            items_df = df[i]
            for index, row in items_df.iterrows():
                # curNode = self.sitesType
                items = items_df.loc[index].tolist()
                # items = self.siteChoice.findItems(site[0], Qt.MatchRecursive | Qt.MatchExactly, 0)
                # Qt.MatchRecursive | Qt.MatchContains|Qt.MatchExactly
                listSubItem = []
                for index in range(0, self.itemTpye.childCount()):
                    listSubItem.append(self.itemTpye.child(index).text(0))
                # print('listSubItem:',listSubItem)
                if items[0] not in listSubItem:
                    self.items1h = QTreeWidgetItem(self.itemTpye)
                    self.items1h.setText(0, items[0])
                    self.items1h.setCheckState(0, Qt.Unchecked)
                else:
                    self.items1h = self.itemTpye.child(listSubItem.index(items[0]))

                # items2h = self.sites1h.findItems(site[1], Qt.MatchExactly, 0)
                self.items2h = QTreeWidgetItem(self.items1h)
                self.items2h.setText(0, items[1])
                self.items2h.setCheckState(0, Qt.Unchecked)

    def get_checked(self, node: QTreeWidgetItem) -> list:
        """ 得到当前节点选中的所有分支， 返回一个 list """
        temp_list = []
        #
        for item in node.takeChildren():
            # 判断是否选中
            if item.checkState(0) == Qt.Checked:
                temp_list.append(item.text(0))
                # 判断是否还有子分支
                if item.childCount():
                    temp_list.extend(self.get_checked(item))
            node.addChild(item)
        print(temp_list)
        return temp_list

    def gen_branch(node: QTreeWidgetItem, texts: list):
        """ 给定某个节点和列表 在该节点生成列表内分支"""
        for text in texts:
            item = QTreeWidgetItem()
            item.setText(0, text)
            item.setCheckState(0, Qt.Unchecked)
            node.addChild(item)

    def table_append(self):
        self.taskList_Table.table_append(self.curSitesList, self.curItemsList, self.sampleDate.text())

    def table_remove(self):
        self.taskList_Table.table_remove()

    def table_read(self):

        if self.showNameYes.isChecked():  # 是否显示监测点位名称
            showName = '是'
        else:
            showName = '否'

        try:
            num = ''.join(re.split(r'[A-Za-z]', self.initsampleID.text()))
            num = int(num) + 1
        except:
            reply = QMessageBox.warning(self, '提醒', "请先输入一个正确的样品编号 ",
                                        QMessageBox.Yes,
                                        QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                return

        df_labes = self.taskList_Table.table_read(self.sampleDate.text(), self.initsampleID.text(), showName)
        dir_printed = self.siteTypeChoice.currentText()
        path = os.path.join(os.path.curdir, '打印记录', dir_printed)
        curtime = time.strftime("%Y%m%d%H%M%S", time.localtime())
        '''
        写入已打印记录
        '''
        if os.path.exists(path):

            path1 = os.path.join(path, curtime + '.xlsx')
            # print('path', path)
            df_labes.to_excel(path1, index=False)
        else:
            os.mkdir(path)
            path2 = os.path.join(path, curtime + '.xlsx')
            # print('path else', path)
            df_labes.to_excel(path2, index=False)

        '''
                生成标签
        '''
        if showName == '否':
            df_labes['点位名称'] = ''

        df_labes['硝酸'] = ''

        df_labels_out = df_labes.to_dict(orient='records')
        print(df_labels_out)
        context = {
            'labels': df_labels_out
            # 'siteName': df_labes_out['点位名称'][0],
            # 'items': df_labes_out['监测项目'][0],
            # 'sampleDate': df_labes_out['监测日期'][0]

        }
        print('render prepare')
        tpl.render(context)
        print('render complete')
        tpl.save(os.path.join(path, curtime + '标签.docx'))
        os.startfile(os.path.join(path, curtime + '标签.docx'))  # windows下成功打开docx

    def getMaxSampleID(self):

        dir_printed = self.siteTypeChoice.currentText()
        path = os.path.join(os.path.curdir, '打印记录', dir_printed)
        print('path', path)
        if os.path.exists(path):
            # df = pd.read_excel(path, keep_default_na=False, header=0, sheet_name=None)
            if self.list_newest_files(path) == '':
                return '未找到历史打印记录，请手动输入开始编号'
            else:
                # print('self.list_newest_files(path)', self.list_newest_files(path))
                df = \
                    pd.read_excel(self.list_newest_files(path), keep_default_na=False,
                                  header=0, sheet_name=None)['Sheet1'][
                        '样品编号']
                print(df)
                return df.max()
        else:
            return '未找到历史打印记录，请手动输入开始编号'

        # print("combox select path", path)

    def list_newest_files(self, rootdir):
        _files = []
        list = os.listdir(rootdir)  # 列出文件夹下所有的目录与文件
        for i in range(0, len(list)):
            path = os.path.join(rootdir, list[i])
            if os.path.isdir(path):
                _files.extend(self.list_newest_files(path))
            if os.path.isfile(path):
                _files.append(path)
        # print('_files', _files)
        _files = [f for f in _files if f.find('~') == -1]  # 去掉隐藏文件
        _files = [f for f in _files if f.find('.xlsx') > -1]  # 仅包含xlsx文件
        # print(_files)
        if len(_files) > 0:
            return _files[-1]
        else:
            return ''

    def sampleIDPlus1(self, sapmeid):

        try:
            print('sapmeid', sapmeid)
            num = ''.join(re.split(r'[A-Za-z]', str(sapmeid)))
            print('num', num)
            num = int(num) + 1

        except:
            reply = QMessageBox.warning(self, '提醒', "请先输入一个正确的样品编号 ",
                                        QMessageBox.Yes,
                                        QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                return
        pre = ''.join(re.split(r'[0-9]', str(sapmeid)))
        # print('pre + str(num)', str(num), pre)
        return pre + str(num)


class TableWidgetClass(QWidget):

    def __init__(self, tablewidget):
        # noinspection PyArgutablewidgetmentList
        super(TableWidgetClass, self).__init__()
        self.tableWidget = None
        self.initui(tablewidget)
        self.twrowcnt = 0

    def initui(self, tablewidget):
        # layout = QHBoxLayout()

        self.tableWidget = tablewidget
        self.tableWidget.setColumnCount(5)
        self.tableWidget.setRowCount(0)

        # 设置头label
        self.tableWidget.setHorizontalHeaderLabels(['点位名称', '个数', '项目名称', '个数', '采样时间'])

        self.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)  # Stretch
        self.tableWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)  # ScrollBarAlwaysOn

        # 设置列宽度

        self.tableWidget.setColumnWidth(0, 300)
        self.tableWidget.setColumnWidth(1, 30)
        self.tableWidget.setColumnWidth(2, 300)
        self.tableWidget.setColumnWidth(3, 30)
        self.tableWidget.setColumnWidth(4, 80)

        # 优化3 将表格变为禁止编辑
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 优化 4 设置表格整行选中
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)

    def table_append(self, sites, items, sampleDate):
        sitesCnt = len(sites)
        sites = ','.join(sites)
        itemsCnt = len(items)
        items = ','.join(items)

        if sites == '' or items == '':
            return
        item = self.tableWidget.findItems(sites, Qt.MatchExactly)
        if not item:
            row = self.tableWidget.rowCount()
            self.tableWidget.insertRow(row)
            newsites = QTableWidgetItem(sites)
            newitems = QTableWidgetItem(items)
            self.tableWidget.setItem(row, 0, newsites)
            self.tableWidget.setItem(row, 1, QTableWidgetItem(str(sitesCnt)))
            self.tableWidget.setItem(row, 2, newitems)
            self.tableWidget.setItem(row, 3, QTableWidgetItem(str(itemsCnt)))
            self.tableWidget.setItem(row, 4, QTableWidgetItem(sampleDate))

    def table_remove(self):
        self.tableWidget.removeRow(self.tableWidget.currentIndex().row())

    # def table_remove(self, str_info):
    #     item = self.tableWidget.findItems(str_info, Qt.MatchExactly)
    #     if item:
    #         row = item[0].row()
    #         self.tableWidget.removeRow(row)

    def table_read(self, date, sampleID, showName):
        row_num = self.tableWidget.rowCount()  # 获取当前的行数
        dic_allSites = {}
        for i in range(row_num):
            sites = self.tableWidget.item(i, 0).text()
            items = self.tableWidget.item(i, 2).text()
            sites = sites.split(",")
            items = items.split(",")
            dic_site = {}  # 列表的每一行，处理成key=点位名，value=项目列表的字典
            for site in sites:
                dic_site[site] = items
            print(dic_site)
            for k, v in dic_site.items():
                if k in dic_allSites.keys():
                    dic_allSites[k] = list(set(dic_allSites[k] + v))
                else:
                    dic_allSites[k] = v
        # print('print(dic_allSites)', dic_allSites)
        path = os.path.join(os.path.curdir, '基础信息', '项目分组方式.xlsx')
        # print("combox select path", path)
        df = pd.read_excel(path, keep_default_na=False, header=0, sheet_name=None)['Sheet1']
        # print('df 项目分组方式 :',df,type(df))
        df_labes = []  # DataFrame(columns=['id', 'siteName', 'items', 'date', 'gudingji', 'rongqi'])
        id = sampleID

        for k, v in dic_allSites.items():
            # print('当前站点名称：', k)
            items_in_oneSite = v
            id = self.sampleIDPlus1(id)
            for index, row in df.iterrows():
                # print('row[包含项目]', row['包含项目'])
                classID = row['分组编号']
                itemClass = row['包含项目'].split(",")
                gudingji = row['固定剂名称']
                rongqi = row['所用容器']
                # print('items_in_oneSite：', items_in_oneSite)
                # print('itemClass：', itemClass)
                intersection = list(set(items_in_oneSite) & set(itemClass))
                print('intersection:', intersection)
                if len(intersection) > 0:
                    # if showName == '否':
                    #     k = ''
                    path = os.path.join(os.path.curdir, 'qrcode.jpg')
                    print('image path', path)
                    # qrcode = docxtpl.InlineImage(tpl, path)
                    # print('qrcodeqrcodeqrcodeqrcodeqrcodeqrcode',qrcode)
                    if classID != '':
                        # df_labes.append([id, k, classID, date, gudingji, rongqi, qrcode])
                        df_labes.append([id, k, classID, date, gudingji, rongqi])
                    elif classID == '':
                        # df_labes.append([id, k, ','.join(intersection), date, gudingji, rongqi, qrcode])
                        df_labes.append([id, k, ','.join(intersection), date, gudingji, rongqi])
                    # qrcode = docxtpl.InlineImage(self.tpl, "./qrcode.jpg")
                    # df_labes.append('qrcode')
                    items_in_oneSite = list(set(items_in_oneSite) - set(intersection))

                    # print('df_labes : ', df_labes)
            if len(items_in_oneSite) >= 20:
                df_labes.append([id, k, ','.join(items_in_oneSite[1:20]) + '...', date, "", ''])
            elif len(items_in_oneSite) > 0:
                df_labes.append([id, k, ','.join(items_in_oneSite), date, "", ''])            
        print('df_labes1 : ', df_labes)
        df_labes = DataFrame(df_labes, columns=['样品编号', '点位名称', '监测项目', '监测日期', '固定剂', '容器'])
        print('df_labes2 : ', df_labes)
        return df_labes

    def sampleIDPlus1(self, sapmeid):
        sapmeid = str(sapmeid)
        num = ''.join(re.split(r'[A-Za-z]', sapmeid))
        num = int(num) + 1

        pre = ''.join(re.split(r'[0-9]', sapmeid))
        # print('pre + str(num)',num,pre)
        return pre + str(num)


class TreeWidgetClass(QWidget):
    pass


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    myshow = SLP()
    myshow.show()
    sys.exit(app.exec_())
